package com.example.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.concurrent.*;

@Slf4j
public class FfmpegUtil {

    public static Boolean changeAmrToMp3(String sourcePath, String targetPath) {
        String webroot = "/usr/bin/ffmpeg";
        Runtime run = Runtime.getRuntime();
        try {
            long start = System.currentTimeMillis();
            //执行ffmpeg.exe,前面是ffmpeg.exe的地址，中间是需要转换的文件地址，后面是转换后的文件地址。-i是转换方式，意思是可编码解码，mp3编码方式采用的是libmp3lame
            //wav转pcm
            //Process p=run.exec(new File(webroot).getAbsolutePath()+"/ffmpeg -y -i "+sourcePath+" -acodec pcm_s16le -f s16le -ac 1 -ar 16000 "+targetPath);
            //mp3转pcm
//            Process p=run.exec(webroot+" -y -i "+sourcePath+" -ar 44100 -ac 2 -acodec mp3 "+targetPath);
            //amr 转 mp3
            String command = webroot + " -y -i " + sourcePath + " -vcodec h264 " + targetPath;
            log.info(command);
            Process p = run.exec(command);

            //释放进程
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            int retCode = p.waitFor();
            log.info("retCode==============" + retCode);
            if (retCode == 0) {
                log.info("ffmpeg程序正常执行结束");
            } else {
                throw new IOException("FFMPEG命令执行异常");
            }
            long end = System.currentTimeMillis();
            log.info(sourcePath + " convert success, costs:" + (end - start) + "ms");
            log.info(targetPath);
            return true;
        } catch (Exception e) {
            log.info("FileFormatTets-------------> " + e);
            e.printStackTrace();
            return false;
        } finally {
            //run调用lame解码器最后释放内存
            run.freeMemory();
        }

    }


    private static ExecutorService pool = Executors.newCachedThreadPool();


    public static Boolean amrToMp3(String sourcePath, String targetPath) {

        //录音文件下拉地址

        String path = "/usr/bin/ffmpeg";

        String mp3Name = sourcePath;

        String wavName = targetPath;

        try {

                String command = "";

                // FFMPEG_PATH ffmpeg路径 如：D:/ffmpeg/bin/ffmpeg.exe

                command = MessageFormat.format("{0} -i {1} -vcodec h264 {2}", path,

                        mp3Name, wavName);

                int n = execCommand(command, 10000);

                // 获取文件流

                if (n == 0) {

//                    body = FileUtil.getFile(PropertiesDef.ORIGIN_PATH, wavName);

                }

            return true;
        } catch (Exception e) {
            log.info("mp3转wav失败", ExceptionUtils.getStackTrace(e));
            return false;

        } finally {

        }

    }


    public static int execCommand(String command, long timeout) {

        Process process = null;

        Future<Integer> executeFuture = null;

        try {

            process = Runtime.getRuntime().exec(command);

            final Process p = process;

            Callable<Integer> call = new Callable<Integer>() {

                @Override

                public Integer call() throws Exception {

                    p.waitFor();

                    return p.exitValue();

                }

            };

            //使用线程池防止Process阻塞

            executeFuture = pool.submit(call);

            return executeFuture.get(timeout, TimeUnit.MILLISECONDS);

        } catch (Exception e) {

            log.info("mp3转wav:execCommand 执行命令失败,command:{}，错误原因:{}", command,
                    ExceptionUtils.getStackTrace(e));
            return 1;

        } finally {

            if (executeFuture != null) {

                try {

                    executeFuture.cancel(true);

                } catch (Exception ignore) {

                }

            }
            if (process != null) {

                process.destroy();

            }
        }
    }
}
